// 没有重复的最长子串
function longestSubStrings(s) {
    let map = new Map();
    let max = 0;
    let i = 0;
    for (let j = 0; j < s.length; j++) {
        if (map.has(s[j])) {
            // j 记录的是数据的索引
            // i 代表的是【最新而非获取s[j]】最远 重复元素最新存在的位置
            i = Math.max(map.get(s[j]) + 1, i)    // map.get(s[j]) 代表的是重复元素存在的位置 +1就是 非重复元素的位置
        }
        // max 老的最长与新的最长比较 新值就是重复位置
        max = Math.max(max, j - i + 1)   // j 是0开始的 所以要加1 只要存在就有1 0-0  // j-i+1 当前位置-最新重复位置得到max
        map.set(s[j], j)  // 记录的每一个元素最新一次出现的位置
    }
    return max
}

console.log(longestSubStrings("jiofajsifodjaisf"))
// ajsifod

// map j=0
// i = 0;
// max = 1

// map j=0 i=1
// i = 0
// max = 2

// map j=0 i=1 0=2
// i = 0;
// max = 3

// ... 到第一个重复位置

// map j=5 i=1 0=2 f=3 a=4
// i = 1
// max = Math.max(5, 5) = 5

//  map j=5 i=1 0=2 f=3 a=4 s=6
// i = 1
// max = Math.max(5, 6) = 6

//  map j=5 [i=1] 0=2 f=3 a=4 s=6 
// i = 2
// max = Math.max(6, 6) = 6
// map j=5 i=7 0=2 f=3 a=4 s=6

//  map j=5 i=7 0=2 [f=3] a=4 s=6  
// i = 4
// max = Math.max(6, 8-4+1) = 6
// map j=5 i=7 0=2 f=8 a=4 s=6

//  map j=5 i=7 [0=2] f=8 a=4 s=6
// i = math.max(3, 4) // 不用max 就会有问题 i就是当前重复项索引 如果用3 后面可能会有重复项 前面循环过程中已经保留了最大max 所以要用最远的哪个非重复项
// max = Math.max(6, 8-4+1) = 6
// map j=5 i=7 0=2 f=8 a=4 s=6